package com.canyinghao.cananimation;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.Color;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import static com.canyinghao.cananimation.CanAnimation.animationTogether;

/**
 * Created by canyinghao on 16/2/16.
 */
public final class CanObjectAnimator {
    static final HiLogLabel logLabel = new HiLogLabel(HiLog.LOG_APP, 0x00101, "CanObjectAnimator");
    private Component mView;

    private CanObjectAnimator(Component view) {
        this.mView = view;
    }

    public static CanObjectAnimator on(final Component view) {

        return new CanObjectAnimator(view);
    }

    private void setProperties(AnimatorProperty animator, float duration, int interpolator) {
        if (duration < 0) {
            duration = 0;
        }
        animator.setDuration((long) (duration * 1000));

        if (interpolator != -1) {
            animator.setCurveType(interpolator);
        }
    }


    public Animator color(RgbColor from, int to, float duration, int interpolator, boolean isText) {

        AnimatorProperty animator;

        animator = mView.createAnimatorProperty();
        if (mView instanceof Text && isText) {
        } else {


            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(from);

            mView.setBackground(shapeElement);
            // animator = ObjectAnimator.ofInt(mView, "backgroundColor", from, to);
        }

        // setProperties(animator, duration, interpolator);

        //  animator.setEvaluator(new ArgbEvaluator());


        return animator;
    }


    public Animator color(RgbColor from, int to) {
        return color(from, to, 1);
    }


    public Animator color(RgbColor from, int to, float duration) {
        return color(from, to, duration, -1, false);
    }


    //    public Animator colorText(int to) {
//
//        return colorText(to, 1);
//    }
//
//
//    public Animator colorText(int to, float duration) {
//
//        RgbColor from = RgbColor.;
//
//        if (mView instanceof Component) {
//
//            Text tv = (Text) mView;
//
//            from = tv.getTextColor()
//        }
//        return color(from, to, duration, -1, true);
//    }


    public Animator colorText(RgbColor from, int to) {
        return color(from, to, 1, 1, true);
    }


    public Animator colorText(RgbColor from, int to, float duration) {
        return color(from, to, duration, 1, true);
    }


    /**
     * Animates transition between current  rotation to target rotation
     *
     * @param fromRotation
     * @param toRotation
     * @param duration
     * @param interpolator 插值器
     * @param isFrom
     * @return Animator
     */

    public Animator rotate(float fromRotation, float toRotation, float duration, int interpolator, boolean isFrom) {

        AnimatorProperty animator;
        if (isFrom) {
            animator = mView.createAnimatorProperty().rotate(fromRotation);
        } else {
            animator = mView.createAnimatorProperty().rotate(toRotation);
        }
        setProperties(animator, duration, interpolator);
        return animator;
    }


    public Animator rotate(float rotation, float duration, int interpolator, boolean isFrom) {

        HiLog.debug(logLabel, "rotations:" + mView.getRotation());
        return rotate(mView.getRotation(), rotation, duration, interpolator, isFrom);
    }


//    /**
//     * Animates transition between current  rotationX to target rotationX
//     *
//     * @param rotationX
//     * @param duration
//     * @param interpolator
//     * @param isFrom
//     * @return
//     */

//    public Animator rotateX(float rotationX, float duration, int interpolator, boolean isFrom) {
//
//        AnimatorProperty animator;
//        if (isFrom) {
//            animator = ObjectAnimator.ofFloat(mView, "rotationX", rotationX, mView.getRotationX());
//        } else {
//            animator = ObjectAnimator.ofFloat(mView, "rotationX", mView.getRotationX(), rotationX);
//        }
//
//
//        setProperties(animator, duration, interpolator);
//
//        return animator;
//    }

//    /**
//     * Animates transition between current  rotateY to target rotateY
//     *
//     * @param rotationY
//     * @param duration
//     * @param interpolator
//     * @param isFrom
//     * @return
//     */
//
//    public Animator rotateY(float rotationY, float duration, int interpolator, boolean isFrom) {
//
//        AnimatorProperty animator;
//        if (isFrom) {
//            animator = ObjectAnimator.ofFloat(mView, "rotationY", rotationY, mView.getRotationX());
//        } else {
//            animator = ObjectAnimator.ofFloat(mView, "rotationY", mView.getRotationX(), rotationY);
//        }
//
//
//        setProperties(animator, duration, interpolator);
//
//        return animator;
//    }


    public Animator rotateFrom(float rotation) {
        return rotateFrom(rotation, 1);
    }


    public Animator rotateFrom(float rotation, float duration) {
        return rotateFrom(rotation, duration, -1);
    }


    public Animator rotateFrom(float rotation, float duration, int interpolator) {
        return rotate(rotation, duration, interpolator, true);
    }


    public Animator rotateFrom(float fromRotation, float toRotation, float duration) {
        return rotate(fromRotation, toRotation, duration, -1, true);
    }


    public Animator rotateFrom(float fromRotation, float toRotation, float duration, int interpolator) {
        return rotate(fromRotation, toRotation, duration, interpolator, true);
    }


    public Animator rotateTo(float rotation) {
        return rotateTo(rotation, 1);
    }


    public Animator rotateTo(float rotation, float duration) {
        return rotateTo(rotation, duration, -1);
    }


    public Animator rotateTo(float rotation, float duration, int interpolator) {
        return rotate(rotation, duration, interpolator, false);
    }


    public Animator rotateTo(float fromRotation, float toRotation, float duration) {
        return rotate(fromRotation, toRotation, duration, -1, false);
    }


    public Animator rotateTo(float fromRotation, float toRotation, float duration, int interpolator) {
        return rotate(fromRotation, toRotation, duration, interpolator, false);
    }


    /**
     * Animates transition between current  scaleX,scaleY to target scaleX,scaleY
     *
     * @param fromScaleX
     * @param toScaleX
     * @param fromScaleY
     * @param toScaleY
     * @param duration
     * @param interpolator
     * @param isFrom
     * @return Animator
     */

    public Animator scale(float fromScaleX, float toScaleX, float fromScaleY, float toScaleY, float duration, int interpolator, boolean isFrom) {


        AnimatorProperty animatorX;
        AnimatorProperty animatorY;

        if (isFrom) {
            animatorX = mView.createAnimatorProperty().scaleX(fromScaleX).scaleXFrom(toScaleX);
            animatorY = mView.createAnimatorProperty().scaleY(fromScaleY).scaleYFrom(toScaleY);
        } else {
            animatorX = mView.createAnimatorProperty().scaleX(toScaleX).scaleXFrom(fromScaleX);
            animatorY = mView.createAnimatorProperty().scaleY(toScaleY).scaleYFrom(fromScaleY);
        }


        setProperties(animatorX, duration, interpolator);
        setProperties(animatorY, duration, interpolator);

        return animationTogether(animatorX, animatorY);
    }


    public Animator scale(float targetX, float targetY, float duration, int interpolator, boolean isFrom) {
        float currentX = mView.getScaleX();
        float currentY = mView.getScaleY();

        HiLog.debug(logLabel, "scalx:" + mView.getScaleX() + "++++scaleY:" + mView.getScaleY());

        return scale(currentX, targetX, currentY, targetY, duration, interpolator, isFrom);
    }


    public Animator scaleTo(float scaleX, float scaleY) {
        return scaleTo(scaleX, scaleY, 1);
    }


    public Animator scaleTo(float scaleX, float scaleY, float duration) {
        return scaleTo(scaleX, scaleY, duration, -1);
    }


    public Animator scaleTo(float scaleX, float scaleY, float duration, int interpolator) {
        return scale(scaleX, scaleY, duration, interpolator, false);
    }


    public Animator scaleTo(float fromScaleX, float toScaleX, float fromScaleY, float toScaleY, float duration) {
        return scale(fromScaleX, toScaleX, fromScaleY, toScaleY, duration, -1, false);
    }


    public Animator scaleTo(float fromScaleX, float toScaleX, float fromScaleY, float toScaleY, float duration, int interpolator) {
        return scale(fromScaleX, toScaleX, fromScaleY, toScaleY, duration, interpolator, false);
    }


    public Animator scaleFrom(float scaleX, float scaleY) {
        return scaleFrom(scaleX, scaleY, 1);
    }


    public Animator scaleFrom(float scaleX, float scaleY, float duration) {
        return scaleFrom(scaleX, scaleY, duration, -1);
    }


    public Animator scaleFrom(float scaleX, float scaleY, float duration, int interpolator) {
        return scale(scaleX, scaleY, duration, interpolator, true);
    }


    public Animator scaleFrom(float fromScaleX, float toScaleX, float fromScaleY, float toScaleY, float duration) {
        return scale(fromScaleX, toScaleX, fromScaleY, toScaleY, duration, -1, true);
    }


    public Animator scaleFrom(float fromScaleX, float toScaleX, float fromScaleY, float toScaleY, float duration, int interpolator) {
        return scale(fromScaleX, toScaleX, fromScaleY, toScaleY, duration, interpolator, true);
    }


    /**
     * Animates transition between current  x,y to target x,y
     *
     * @param fromX
     * @param toX
     * @param fromY
     * @param toY
     * @param duration
     * @param interpolator
     * @param isFrom
     * @return Animator
     */

    public Animator move(float fromX, float toX, float fromY, float toY, float duration, int interpolator, boolean isFrom) {


        AnimatorProperty animatorX;
        AnimatorProperty animatorY;

        if (isFrom) {
            animatorX = mView.createAnimatorProperty().moveToX(fromX).moveFromX(toX);
            animatorY = mView.createAnimatorProperty().moveToY(fromY).moveFromY(toY);
        } else {
            animatorX = mView.createAnimatorProperty().moveToX(toX).moveFromX(fromX);
            animatorY = mView.createAnimatorProperty().moveToY(toY).moveFromY(fromY);
        }

        setProperties(animatorX, duration, -1);
        setProperties(animatorY, duration, -1);

        return animationTogether(animatorX, animatorY);


    }


    public Animator move(float targetX, float targetY, float duration, int interpolator, boolean isFrom) {

        float currentX = mView.getContentPositionX();
        float currentY = mView.getContentPositionY();


        return move(currentX, targetX, currentY, targetY, duration, interpolator, isFrom);

    }


    public Animator moveFrom(float x, float y) {
        return moveFrom(x, y, 1);
    }


    public Animator moveFrom(float x, float y, float duration) {
        return moveFrom(x, y, duration, -1);
    }


    public Animator moveFrom(float x, float y, float duration, int interpolator) {
        return move(x, y, duration, interpolator, true);
    }


    public Animator moveFrom(float fromX, float toX, float fromY, float toY, float duration) {
        return move(fromX, toX, fromY, toY, duration, -1, true);
    }


    public Animator moveFrom(float fromX, float toX, float fromY, float toY, float duration, int interpolator) {
        return move(fromX, toX, fromY, toY, duration, interpolator, true);
    }


    public Animator moveTo(float x, float y) {
        return moveTo(x, y, 1);
    }


    public Animator moveTo(float x, float y, float duration) {
        return moveTo(x, y, duration, -1);
    }


    public Animator moveTo(float x, float y, float duration, int interpolator) {
        return move(x, y, duration, interpolator, false);
    }


    public Animator moveTo(float fromX, float toX, float fromY, float toY, float duration) {
        return move(fromX, toX, fromY, toY, duration, -1, false);
    }


    public Animator moveTo(float fromX, float toX, float fromY, float toY, float duration, int interpolator) {
        return move(fromX, toX, fromY, toY, duration, interpolator, false);
    }


    /**
     * Animates transition between current  alpha to target alpha
     *
     * @param fromAlpha
     * @param toAlpha
     * @param duration
     * @param interpolator
     * @param isFrom
     * @return Animator
     */

    public Animator alpha(float fromAlpha, float toAlpha, float duration, int interpolator, boolean isFrom) {

        AnimatorProperty animator;
        if (isFrom) {
            animator = mView.createAnimatorProperty().alpha(toAlpha).alphaFrom(fromAlpha);
        } else {
            animator = mView.createAnimatorProperty().alpha(fromAlpha).alpha(toAlpha);
        }

        setProperties(animator, duration, interpolator);

        return animator;
    }


    public Animator alpha(float toAlpha, float duration, int interpolator, boolean isFrom) {


        return alpha(mView.getAlpha(), toAlpha, duration, interpolator, isFrom);
    }


    public Animator alphaFrom(float toAlpha) {
        return alphaFrom(toAlpha, 1);
    }


    public Animator alphaFrom(float toAlpha, float duration) {
        return alphaFrom(toAlpha, duration, -1);
    }


    public Animator alphaFrom(float toAlpha, float duration, int interpolator) {
        return alpha(toAlpha, duration, interpolator, true);
    }


    public Animator alphaFrom(float fromAlpha, float toAlpha, float duration) {
        return alpha(fromAlpha, toAlpha, duration, -1, true);
    }


    public Animator alphaFrom(float fromAlpha, float toAlpha, float duration, int interpolator) {
        return alpha(fromAlpha, toAlpha, duration, interpolator, true);
    }


    public Animator alphaTo(float toAlpha) {
        return alphaTo(toAlpha, -1);
    }


    public Animator alphaTo(float toAlpha, float duration) {
        return alphaTo(toAlpha, duration, -1);
    }


    public Animator alphaTo(float toAlpha, float duration, int interpolator) {
        return alpha(toAlpha, duration, interpolator, false);
    }


    public Animator alphaTo(float fromAlpha, float toAlpha, float duration) {
        return alpha(fromAlpha, toAlpha, duration, -1, false);
    }


    public Animator alphaTo(float fromAlpha, float toAlpha, float duration, int interpolator) {
        return alpha(fromAlpha, toAlpha, duration, interpolator, false);
    }


}
